<script setup lang="ts">
import { ref, computed, reactive, watch, nextTick, onMounted } from 'vue'
import CalculationModal from './CalculationModal.vue'; // 导入计算弹窗组件
import ResultModal from './ResultModal.vue'; // 导入结果弹窗组件
import icon0 from '../../assets/icon/icon0.svg'
import iconCompare from '../../assets/file-spreadsheet.svg'
import iconChart from '../../assets/chart.svg'
import CardLine from './components/card-line.vue'
import SamplingChart from './components/sampling-chart.vue' // 导入采样概率图表组件
import MatrixTable from './components/MatrixTable.vue'
import video53before from '../../assets/video/before5node3flow.mp4'
import video53after from '../../assets/video/after5node3flow.mp4'
import video52before from '../../assets/video/before5node2flow.mp4'
import video52after from '../../assets/video/after5node2flow.mp4'
import video43before from '../../assets/video/before4node3flow.mp4'
import video43after from '../../assets/video/after4node3flow.mp4'
import video42before from '../../assets/video/before4node2flow.mp4'
import video42after from '../../assets/video/after4node2flow.mp4'

// 5节点的配置
const nodesConfig5 = [
  { id: 'V1', x: 400, y: 100 },
  { id: 'V2', x: 200, y: 200 },
  { id: 'V3', x: 200, y: 400 },
  { id: 'V4', x: 400, y: 400 },
  { id: 'V5', x: 600, y: 300 }
]

const videoSrc = computed(() => {
  if (nodeCount.value === 5 && flowCount.value === 3) {
    return showResultPanel.value ? video53after : video53before;
  } else if (nodeCount.value === 5 && flowCount.value === 2) {
    return showResultPanel.value ? video52after : video52before;
  } else if (nodeCount.value === 4 && flowCount.value === 3) {
    return showResultPanel.value ? video43after : video43before;
  } else {
    return showResultPanel.value ? video42after : video42before;
  }
});

// 4节点的配置
const nodesConfig4 = [
  { id: 'V1', x: 400, y: 100 },
  { id: 'V2', x: 200, y: 200 },
  { id: 'V3', x: 200, y: 400 },
  { id: 'V4', x: 400, y: 400 }
]

const calcResult = [
  [{
    VNFCount: 3,
    percent: 100,
    time: 0.77,
    bestPercent: 23
  }, // 相干光量子
  {
    VNFCount: 5,
    percent: 100,
    time: 58.35,
  }, // 模拟退火
  {
    VNFCount: 4,
    percent: 78.57,
    time: 142.65,
  }], // 禁忌 // 53
  [{
    VNFCount: 2,
    percent: 100,
    time: 0.82,
    bestPercent: 40
  }, // 相干光量子
  {
    VNFCount: 3,
    percent: 87.5,
    time: 54.43,
  }, // 模拟退火
  {
    VNFCount: 2,
    percent: 87.5,
    time: 47.21,
  }], // 禁忌 // 52
  [{
    VNFCount: 3,
    percent: 100,
    time: 18.46,
    bestPercent: 43
  }, // 相干光量子
  {
    VNFCount: 9,
    percent: 100,
    time: 57.92,
  }, // 模拟退火
  {
    VNFCount: 2,
    percent: 78.57,
    time: 53.07,
  }], // 禁忌 // 43
  [{
    VNFCount: 2,
    percent: 100,
    time: 1.77,
    bestPercent: 30
  }, // 相干光量子
  {
    VNFCount: 7,
    percent: 100,
    time: 56.46,
  }, // 模拟退火
  {
    VNFCount: 2,
    percent: 75,
    time: 43.13,
  }] // 禁忌 // 42
]

const squareResult = [
  [ // 5节点3流
    { // 相干光量子分配方案
      nodes: ['v1', 'v2', 'v3', 'v4', 'v5'],
      data: [
        { flow: 'f1', values: [0, 2, null, null, 0] },
        { flow: 'f2', values: [null, 2, 1, 0, null] },
        { flow: 'f3', values: [3, null, 4, 0, null] },
        { flow: 'xi', values: [1, 1, 1, null, null] }
      ]
    },
    { // 模拟退火算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4', 'v5'],
      data: [
        { flow: 'f1', values: [0, 0, null, null, 2] },
        { flow: 'f2', values: [null, 0, 0, 3, null] },
        { flow: 'f3', values: [2, null, 3, 2, null] },
        { flow: 'xi', values: [1, 0, 1, 2, 1] }
      ]
    },
    { // 禁忌搜索算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4', 'v5'],
      data: [
        { flow: 'f1', values: [0, 0, null, null, 1] },
        { flow: 'f2', values: [null, 0, 4, 0, null] },
        { flow: 'f3', values: [0, null, 6, 0, null] },
        { flow: 'xi', values: [0, 0, 2, 0, 2] }
      ]
    }
  ],
  [ // 5节点2流
    { // 相干光量子分配方案
      nodes: ['v1', 'v2', 'v3', 'v4', 'v5'],
      data: [
        { flow: 'f1', values: [5, 1, null, null, 0] },
        { flow: 'f2', values: [null, 3, 0, 0, null] },
        { flow: 'xi', values: [1, 1, 0, 0, 0] }
      ]
    },
    { // 模拟退火算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4', 'v5'],
      data: [
        { flow: 'f1', values: [0, 1, null, null, 5] },
        { flow: 'f2', values: [null, 0, 0, 4, null] },
        { flow: 'xi', values: [0, 1, 0, 1, 1] }
      ]
    },
    { // 禁忌搜索算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4', 'v5'],
      data: [
        { flow: 'f1', values: [5, 1, null, null, 0] },
        { flow: 'f2', values: [null, 4, 0, 0, null] },
        { flow: 'xi', values: [1, 1, 0, 0, 0] }
      ]
    }
  ],
  [ // 4节点3流
    { // 相干光量子分配方案
      nodes: ['v1', 'v2', 'v3', 'v4'],
      data: [
        { flow: 'f1', values: [1, 0, null, 1] },
        { flow: 'f2', values: [null, 0, 0, 3] },
        { flow: 'f3', values: [3, null, 0, 4] },
        { flow: 'xi', values: [1, 0, 0, 2] }
      ]
    },
    { // 模拟退火算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4'],
      data: [
        { flow: 'f1', values: [0, 2, null, 0] },
        { flow: 'f2', values: [null, 1, 2, 0] },
        { flow: 'f3', values: [0, null, 7, 0] },
        { flow: 'xi', values: [3, 1, 3, 2] }
      ]
    },
    { // 禁忌搜索算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4'],
      data: [
        { flow: 'f1', values: [0, 0, null, 1] },
        { flow: 'f2', values: [null, 0, 1, 2] },
        { flow: 'f3', values: [0, null, 0, 6] },
        { flow: 'xi', values: [0, 0, 0, 2] }
      ]
    }
  ],
  [ // 4节点2流
    { // 相干光量子分配方案
      nodes: ['v1', 'v2', 'v3', 'v4'],
      data: [
        { flow: 'f1', values: [1, 0, null, 5] },
        { flow: 'f2', values: [3, null, 0, null] },
        { flow: 'xi', values: [1, 0, 0, 1] }
      ]
    },
    { // 模拟退火算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4'],
      data: [
        { flow: 'f1', values: [2, 4, null, 0] },
        { flow: 'f2', values: [1, null, 2, null] },
        { flow: 'xi', values: [1, 2, 2, 2] }
      ]
    },
    { // 禁忌搜索算法分配方案
      nodes: ['v1', 'v2', 'v3', 'v4'],
      data: [
        { flow: 'f1', values: [1, 0, null, 5] },
        { flow: 'f2', values: [4, null, 2, null] },
        { flow: 'xi', values: [1, 0, 0, 1] }
      ]
    }
  ]
]

// 当前选择的节点数量：4或5
const nodeCount = ref(5)

// 节点数据，根据节点数量动态计算
const nodes = computed(() => {
  return nodeCount.value === 5 ? nodesConfig5 : nodesConfig4
})

// 采样概率数据
const samplingData = [
  [  // 53 - 量子计算采样数据
    { value: 24, name: '3.0' },
    { value: 19, name: '4.0' },
    { value: 8, name: '5.0' },
    { value: 19, name: 'unsatisfied_num=1' },
    { value: 16, name: 'unsatisfied_num=2' },
    { value: 5, name: 'unsatisfied_num=3' },
    { value: 5, name: 'unsatisfied_num=4' },
    { value: 2, name: 'unsatisfied_num=5' },
    { value: 1, name: 'unsatisfied_num=6' },
    { value: 2, name: 'unsatisfied_num=7' }
  ],
  [  // 52 - 量子计算采样数据
    { value: 40, name: '2.0' },
    { value: 12, name: '3.0' },
    { value: 6, name: 'unsatisfied_num=1' },
    { value: 2, name: 'unsatisfied_num=10' },
    { value: 6, name: 'unsatisfied_num=2' },
    { value: 6, name: 'unsatisfied_num=3' },
    { value: 6, name: 'unsatisfied_num=4' },
    { value: 6, name: 'unsatisfied_num=5' },
    { value: 6, name: 'unsatisfied_num=6' },
    { value: 5, name: 'unsatisfied_num=7' },
    { value: 4, name: 'unsatisfied_num=8' },
    { value: 1, name: 'unsatisfied_num=9' },
  ],
  [  // 43 - 量子计算采样数据
    { value: 43, name: '3.0' },
    { value: 10, name: '4.0' },
    { value: 1, name: '5.0' },
    { value: 11, name: 'unsatisfied_num=1' },
    { value: 11, name: 'unsatisfied_num=2' },
    { value: 11, name: 'unsatisfied_num=3' },
    { value: 5, name: 'unsatisfied_num=4' },
    { value: 4, name: 'unsatisfied_num=5' },
    { value: 2, name: 'unsatisfied_num=6' }
  ],
  [  // 42 - 量子计算采样数据
    { value: 30, name: '2.0' },
    { value: 10, name: '3.0' },
    { value: 19, name: '4.0' },
    { value: 11, name: 'unsatisfied_num=1' },
    { value: 11, name: 'unsatisfied_num=2' },
    { value: 11, name: 'unsatisfied_num=3' },
    { value: 6, name: 'unsatisfied_num=4' },
    { value: 2, name: 'unsatisfied_num=6' },
  ]
]

// 当前采样概率数据
const currentSamplingData = ref(samplingData[0])


// 数据流数量
const flowCount = ref(3)


// 可视化类型：'qubo' 或 '3d'
const visualizationType = ref('qubo')

const setVisualizationType = (type: string) => {
  visualizationType.value = type
  showResultModal.value = true
}

const setNodeCount = (count: number) => {
  nodeCount.value = count
}

const setFlowCount = (count: number) => {
  flowCount.value = count
}

// 暴露在背景的公式
type FlowConfigKey = '5-3' | '5-2' | '4-3' | '4-2';

const flowFormulasConfig: Record<FlowConfigKey, string[]> = {
  '5-3': [
    '流f_1, 经过的路径为P_1={v_1,v_2,v_5}',
    '流f_2, 经过的路径为P_2={v_2,v_3,v_4}',
    '流f_3, 经过的路径为P_3={v_1,v_3,v_4}'
  ],
  '5-2': [
    '流f_1, 经过的路径为P_1={v_1,v_2,v_5}',
    '流f_2, 经过的路径为P_2={v_2,v_3,v_4}'
  ],
  '4-3': [
    '流f_1, 经过的路径为P_1={v_1,v_2,v_4}',
    '流f_2, 经过的路径为P_2={v_2,v_3,v_4}',
    '流f_3, 经过的路径为P_3={v_1,v_3,v_4}'
  ],
  '4-2': [
    '流f_1, 经过的路径为P_1={v_1,v_2,v_4}',
    '流f_2, 经过的路径为P_2={v_1,v_3}'
  ]
}

// 动态生成公式
const flowFormulas = computed(() => {
  const key = `${nodeCount.value}-${flowCount.value}` as FlowConfigKey;
  return flowFormulasConfig[key] || [];
});

const showResultPanel = ref(false)

// 弹窗控制
const showCalculationModal = ref(false);
const showResultModal = ref(false);
const state = reactive({calcStart: false})
const calculationResults = ref({
  quantumTime: 0,
  classicalTime: 0,
  optimality: 0,
  vnfCount: 0
});

// 开始计算
const startCalculation = () => {
  showCalculationModal.value = true;
  state.calcStart = true
  changeCalcResult()
};

// 重新计算
const backCalculation = () => {
  showResultPanel.value = false
  activeTab.value = 'result'
};

// 关闭计算弹窗
const closeCalculationModal = () => {
  showCalculationModal.value = false;
  // 重置动画状态，确保下次打开时动画从头开始
  state.calcStart = false;
};

// 打开结果弹窗
const openResultModal = (results: {
  quantumTime: number;
  classicalTime: number;
  optimality: number;
  vnfCount: number;
}) => {
  calculationResults.value = results;
  // 使用计算结果直接显示结果页面，而不是弹出结果弹窗
  showResultPanel.value = true;
};

const activeTab = ref('result')

const switchTab = (tab: string) => {
  activeTab.value = tab;
};

const currentCalcResult = ref(calcResult[0])

// 关闭结果弹窗
const closeResultModal = () => {
  showResultModal.value = false;
};

// 当前矩阵数据
const currentSquareResult = computed(() => {
  let nodeIndex = 0;
  
  if (nodeCount.value === 5 && flowCount.value === 3) {
    nodeIndex = 0;
  } else if (nodeCount.value === 5 && flowCount.value === 2) {
    nodeIndex = 1;
  } else if (nodeCount.value === 4 && flowCount.value === 3) {
    nodeIndex = 2;
  } else if (nodeCount.value === 4 && flowCount.value === 2) {
    nodeIndex = 3;
  }
  
  return squareResult[nodeIndex];
});

const changeCalcResult = () => {
  if (activeTab.value === 'result') {
    if(nodeCount.value === 5 && flowCount.value === 3) {
      currentCalcResult.value = calcResult[0]
      currentSamplingData.value = samplingData[0]
    } else if (nodeCount.value === 5 && flowCount.value === 2) {
      currentCalcResult.value = calcResult[1]
      currentSamplingData.value = samplingData[1]
    } else if (nodeCount.value === 4 && flowCount.value === 3) {
      currentCalcResult.value = calcResult[2]
      currentSamplingData.value = samplingData[2]
    } else if (nodeCount.value === 4 && flowCount.value === 2) {
      currentCalcResult.value = calcResult[3]
      currentSamplingData.value = samplingData[3]
    }
  }
};

// 视频元素引用
const videoElement = ref<HTMLVideoElement | null>(null)

// 视频加载状态
const isVideoLoading = ref(true)

// 处理视频加载完成事件
const handleVideoLoaded = () => {
  // 短暂延迟后隐藏加载状态，确保过渡平滑
  setTimeout(() => {
    isVideoLoading.value = false;
  }, 300);
};

// 处理视频播放错误
const handleVideoError = () => {
  // 尝试恢复播放
  isVideoLoading.value = false;
};

// 监控nodeCount和flowCount的变化
watch([nodeCount, flowCount, showResultPanel], () => {
  // 设置加载状态为true
  isVideoLoading.value = true;
  nextTick(() => {
    if (videoElement.value) {
      try {
        videoElement.value.load();
      } catch (error) {
        isVideoLoading.value = false;
      }
    }
  });
}, { immediate: true });

// 格式化公式文本，将数字转为角标
const formatFormula = (formula: string) => {
  // 替换 v_1, v_2 等格式为 v<sub>1</sub>
  const formattedText = formula.replace(/([a-zA-Z])_(\d+)/g, '$1<sub>$2</sub>');
  return formattedText;
};

const handleHoverContent = computed(() => {
  if (nodeCount.value === 5 && flowCount.value === 3) {                                                                                                                                          // ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉
    return `伊辛模型优化的目标函数表示网络中所需的最小VNF实例总数，其物理意义在于通过在适当的节点上部署最少的VNF实例，高效处理所有数据流，从而降低网络运营成本和资源占用。相干伊辛机的优化结果为：流f1 沿路径{v1,v2,v5}传输，其中 v1 处理 0 单位数据，v2 处理 2 单位数据，v5处理 0单位数据；流 f2 沿路径 {v2,v3,v4}传输，其中v2处理 2 单位数据，v3处理 1 单位数据，v4 处理 0 单位数据；流 f3 沿路径{v1,v3,v4} 传输，其中 v1 处理 3 单位数据，v3处理 4 单位数据，v4 处理 0 单位数据。节点 v1 触发 1 个VNF实例（处理 3 单位数据），v2触发 1 个VNF实例（处理 4 单位数据），v3触发 1 个VNF实例（处理 5 单位数据），v4 和 v5 各触发 0 个VNF实例，总计 3 个VNF实例。该方案满足流需求约束（流j的总处理量等于 d<sub>j</sub>）和节点资源约束（每个节点的分配资源不超过 x<sub>i</sub>R, 即VNF实例数量乘以单个VNF的计算资源数量）。`.replace(/([vf])(\d+)/g, '$1<sub>$2</sub>');
  } else if (nodeCount.value === 5 && flowCount.value === 2) {
    return `伊辛模型的目标函数优化旨在通过最小化VNF实例数量，降低网络中计算资源的部署成本，同时保证数据流处理需求的完全满足。优化结果为：流 f1沿路径{v1,v2,v5}传输，其中 v1处理 5 单位数据，v2处理 1 单位数据，v5处理 0 单位数据；流 f2 沿路径 {v2,v3,v4} 传输，其中 v2处理 3 单位数据，v3处理 0 单位数据，v4处理 0 单位数据。节点 v1触发 1 个VNF实例（处理 5 单位数据），v2触发 1 个VNF实例（处理 4 单位数据），v3, v4 和 v5 各触发 0 个VNF实例，总计 2 个VNF实例。该方案满足流需求约束（流j的总处理量等于 d<sub>j</sub>）和节点资源约束（每个节点的分配资源不超过 x<sub>i</sub>R, 即VNF实例数量乘以单个VNF的计算资源数量）。`.replace(/([vf])(\d+)/g, '$1<sub>$2</sub>');
  } else if (nodeCount.value === 4 && flowCount.value === 3) {
    return '伊辛模型优化的目标函数表示通过最小化VNF实例数量实现高效的网络资源分配，其物理意义在于优化计算资源利用率，降低网络部署和维护成本。优化结果为：流 f1沿路径 {v1,v2,v4}传输，其中 v1 处理 1 单位数据，v2处理 0 单位数据，v4处理 1 单位数据；流 f2 沿路径 {v2,v3,v4} 传输，其中 v2处理 0 单位数据，v3 处理 0 单位数据，v4处理 3 单位数据；流 f3 沿路径 {v1,v3,v4} 传输，其中 v1 处理 3 单位数据，v3处理 0 单位数据，v4处理 4 单位数据。节点 v1触发 1 个VNF实例（处理 4 单位数据），v触发 0 个VNF实例，v3触发 0 个VNF实例，v4触发 2个VNF实例（处理 8单位数据），总计 3 个VNF实例。该方案满足流需求约束（流j的总处理量等于 d<sub>j</sub>）和节点资源约束（每个节点的分配资源不超过 x<sub>i</sub>R, 即VNF实例数量乘以单个VNF的计算资源数量）。'.replace(/([vf])(\d+)/g, '$1<sub>$2</sub>');  
  } else if (nodeCount.value === 4 && flowCount.value === 2) {
    return '目标函数的优化反映了通过最少VNF实例实现数据流处理的最优资源配置，物理意义在于降低网络硬件和能耗成本，同时确保服务质量。优化结果为：流 f1沿路径 {v1,v2,v4} 传输，其中 v1处理 1 单位数据，v2处理 0 单位数据，v4处理 5 单位数据；流 f2 沿路径{v1,v3} 传输，其中 v1 处理 3 单位数据，v3 处理 0 单位数据。节点 v1 触发 1 个VNF实例（处理 4 单位数据），v2触发 0 个VNF实例，v3 触发 0个VNF实例，v4 触发 1 个VNF实例（处理 5 单位数据），总计 2 个VNF实例。该方案满足流需求约束（流j的总处理量等于 d<sub>j</sub>）和节点资源约束（每个节点的分配资源不超过x<sub>i</sub>R, 即VNF实例数量乘以单个VNF的计算资源数量）。'.replace(/([vf])(\d+)/g, '$1<sub>$2</sub>');
  }
});

</script>

<template>
  <div class="quantum-wraper">
    <div class="header bg-black w-full h-[6.91vh] flex justify-between pr-[2.78vw] pl-[1.66vw]">
      <div class="">
        <img class="h-full w-[20vw]" src="../../assets/logo-white.png" />
      </div>
      <button class="text-[1vw]" @click="$router.push('/')">返回首页</button>
    </div>
    <div class="quantum-visual">
      <div class="canvas">
        <div class="absolute inset-0 w-full h-full overflow-hidden">
          <!-- 加载遮罩层 -->
          <div v-if="isVideoLoading" class="video-loading-mask">
            <div class="loading-spinner"></div>
          </div>
          
          <video 
            ref="videoElement"
            class="w-full h-full object-cover"
            :class="{ 'video-zoom-5': nodeCount === 5, 'video-zoom-4': nodeCount === 4 }"
            autoplay
            loop
            muted
            playsinline
            :key="`${nodeCount}-${flowCount}-${showResultPanel ? 'after' : 'before'}`"
            @loadeddata="handleVideoLoaded"
            @error="handleVideoError"
          >
            <source :src="videoSrc" type="video/mp4" />
            您的浏览器不支持视频播放
          </video>
        </div>
      </div>
  
      <!-- 控制面板 -->
      <div v-if="!showResultPanel" class="control-panel">
        <div class="flex flex-col h-full">
          <div class="flex-grow">
            <div class="panel-section mb-[5.93vh]">
              <div class="section-title">
                <img class="icon" :src="icon0" alt="可视化" />
                数据可视化
              </div>
              <div class="visualization-options">
                <button 
                  class="control-btn" 
                  @click="setVisualizationType('qubo')"
                >
                  QUBO矩阵
                </button>
                <button 
                  class="control-btn" 
                  @click="setVisualizationType('3d')"
                >
                  3D可视化展示
                </button>
              </div>
            </div>
      
            <div class="panel-section">
              <h2 class="section-title">
                <img class="icon" :src="icon0" alt="数据" />
                数据输入
              </h2>
              <div class="input-options">
                <div class="input-group mb-[20px]">
                  <label>网络服务节点</label>
                  <div class="node-options">
                    <button class="node-btn" :class="{ active: nodeCount === 4 }" @click="setNodeCount(4)">4节点</button>
                    <button class="node-btn" :class="{ active: nodeCount === 5 }" @click="setNodeCount(5)">5节点</button>
                  </div>
                </div>
                <div class="input-group">
                  <label>数据流数量</label>
                  <div class="flow-options">
                    <button class="flow-btn" :class="{ active: flowCount === 2 }" @click="setFlowCount(2)">2数据流</button>
                    <button class="flow-btn" :class="{ active: flowCount === 3 }" @click="setFlowCount(3)">3数据流</button>
                  </div>
                </div>
              </div>
            </div>
          </div>
          
          <div class="mt-auto mb-[8vh]">
            <button 
              class="w-full h-[4.93vh] bg-[#1CC9BE] text-white rounded cursor-pointer tracking-wider"
              @click="startCalculation"
            >
              开始计算
            </button>
          </div>
        </div>
      </div>
      <div v-else class="w-[24.72vw] h-full bg-black">
        <div class="flex w-full h-[5.93vh] justify-between items-center align-center">
          <div class="tab-item" :class="{'tab-item-active': activeTab === 'result'}" @click="switchTab('result')"><img class="icon" :src="iconCompare" alt="可视化" />计算结果对比</div>
          <div class="tab-item" :class="{'tab-item-active': activeTab === 'path'}" @click="switchTab('path')"><img class="icon" :src="iconChart" alt="可视化" />VNF分配方案对比</div>
        </div>
        <div v-if="activeTab === 'result'" class="flex-grow overflow-auto">
          <div v-for="(item, index) in currentCalcResult" class="calculation-card">
            <div class="flex items-center">
              <img :src="icon0" alt="">
              <div class="ml-[0.6vw]">{{ index === 0? '相干光量子' : index === 1? '模拟退火算法' : '禁忌搜索算法' }}计算结果</div>
            </div>
            <CardLine :result="item"></CardLine>
            <div v-if="index === 0" class="mt-[20px]">
              <div class="text-sm flex items-center align-center">最优解采样概率
                <div class="text-xl ml-2 font-black font-[DIN]">{{item.bestPercent}}%</div>
                <div class="relative ml-2 group">
                  <div class="w-4 h-4 rounded-full border border-white flex items-center justify-center cursor-help">
                    <span class="text-white text-xs">?</span>
                  </div>
                  <div class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 w-[300px] p-3 bg-black/90 rounded text-xs text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none border-[1px] border-[#1CC9BE]">
                    伊辛机多次采样，得到的解的分布如下图所示，标示了目标值和求解成功次数的关系，同时标示了得到的解不满足约束的数量。在该图数据下，得到最优解的概率为{{item.bestPercent}}%
                  </div>
                </div>
              </div>
            </div>
            <div class="w-full">
              <!-- 最优解采样概率图表 -->
              <SamplingChart v-if="index === 0" :data="currentSamplingData"></SamplingChart>
            </div>
          </div>
        </div>
        <div v-else class="p-6 pb-0">
          <div class="flex items-center mb-4">
            <img :src="icon0" alt="">
            <div class="ml-[0.6vw]">VNF方案分配对比</div>
          </div>
          
          <!-- 相干光量子分配方案 -->
          <div class="text-sm flex items-center align-center matrix-title">相干光量子分配方案
                <div class="relative ml-2 group">
                  <div class="w-4 h-4 rounded-full border border-white flex items-center justify-center cursor-help">
                    <span class="text-white text-xs">?</span>
                  </div>
                  <div class="absolute top-full left-1/2 z-10 transform -translate-x-1/2 mb-2 w-[300px] p-3 bg-black/90 rounded text-xs text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none border-[1px] border-[#1CC9BE]" v-html="handleHoverContent">
                  </div>
                </div>
              </div>
          
          <MatrixTable 
            :matrixData="currentSquareResult[0]" 
            title="相干光量子分配方案"
          ></MatrixTable>
          
          <!-- 模拟退火算法分配方案 -->
          <div class="matrix-title">模拟退火算法分配方案</div>
          <MatrixTable 
            :matrixData="currentSquareResult[1]" 
            title="模拟退火算法分配方案"
          ></MatrixTable>
          
          <!-- 禁忌搜索算法分配方案 -->
          <div class="matrix-title">禁忌搜索算法分配方案</div>
          <MatrixTable 
            :matrixData="currentSquareResult[2]" 
            title="禁忌搜索算法分配方案"
          ></MatrixTable>
        </div>
        <div class="p-6">
          <button 
          class="w-full h-[4.93vh] bg-[#1CC9BE] text-white cursor-pointer tracking-wider"
          @click="backCalculation"
        >
          重新计算
        </button>
        </div>
      </div>
    </div>
  
    <!-- 计算加载弹窗 -->
    <CalculationModal 
      v-if="showCalculationModal" 
      :nodeCount="nodeCount" 
      :flowCount="flowCount"
      @close="closeCalculationModal"
      @openResultModal="openResultModal"
      :calcStart="state.calcStart"
    />
    
    <!-- 结果展示弹窗 -->
    <ResultModal
      v-if="showResultModal"
      :params="{nodeCount, flowCount}"
      :visualizationType="visualizationType"
      @close="closeResultModal"
    />
    
    <!-- 底部公式显示 -->
    <div class="flow-formulas">
      <p v-for="(formula, index) in flowFormulas.slice(0, flowCount)" :key="index" v-html="formatFormula(formula)"></p>
    </div>
  </div>
</template>

<style scoped>
.quantum-visual {
  display: flex;
  height: 100vh;
  background-color: #0a0a0a;
  color: #fff;
}

.canvas {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.control-panel {
  width: 24.72vw;
  padding: 24px;
  background: #000000;
  border-left: 1px solid #202424;
  display: flex;
  flex-direction: column;
  position: relative;
}

.section-title {
  color: #fff;
  margin-bottom: 15px;
  font-size: 16px;
  display: flex;
  align-items: center;
}

.icon {
  width: 20px;
  height: 20px;
  margin-right: 4px;
  vertical-align: middle;
}

.visualization-options {
  display: flex;
  justify-content: space-between;
}

.node-btn,
.flow-btn {
  width: 100%;
  height: 3.95vh;
  background: #161919;
  border: 1px solid #323636;
  color: #fff;
  cursor: pointer;
  font-size: 14px;
}

.control-btn {
  width: 10.14vw;
  height: 4.69vh;
  border: 1px solid #323636;
  background: #161919;
  font-size: 14px;
  text-align: center;
  transition: all 0.3s ease;
  color: #fff;
  cursor: pointer;
  border-radius: 4px;
}

.control-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid #5C5F5F;
}

.node-btn.active,
.flow-btn.active {
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid #5C5F5F;
}

.node-btn:hover,
.flow-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid #5C5F5F;
}

.input-group label {
  display: block;
  margin-bottom: 10px;
  color: rgba(255, 255, 255, 0.9);
  font-size: 0.9rem;
}

.node-options,
.flow-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.tab-item {
  width: 50%;
  height: 5.93vh;
  background: black;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.4);
  border-width: 0px 0px 2px 0px;
  border-color: transparent;
  cursor: pointer;
}

.tab-item img.icon {
  opacity: 0.4;
  filter: brightness(0) invert(1);
}

.tab-item-active{
  cursor: pointer;
  color: rgba(255, 255, 255, 1);
  width: 50%;
  height: 5.93vh;
  background: radial-gradient(100% 100% at 50% 100%, rgba(24, 171, 162, 0.5) 0%, rgba(0, 0, 0, 0) 100%), #1B1B1B;
  border-width: 0px 0px 2px 0px;
  border-style: solid;
  border-color: #18ABA2;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tab-item-active img.icon {
  opacity: 1;
  filter: brightness(0) invert(1);
}

.calculation-card {
  width: 100%;
  padding: 24px;
  color: rgba(255, 255, 255, 1);
  border-width: 0px 0px 1px 0px;
  border-color: rgba(255, 255, 255, 0.1);
}

.video-zoom-5 {
  transform: scale(1.1);
  transform-origin: 90% 65%;
}

.video-zoom-4 {
  transform: scale(1.1);
  transform-origin: 50% 65%;
}

.video-loading-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0,1);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10;
}

.loading-spinner {
  width: 50px;
  height: 50px;
  border: 5px solid rgba(28, 201, 190, 0.3);
  border-radius: 50%;
  border-top: 5px solid #1CC9BE;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.flow-formulas {
  position: absolute;
  bottom: 20px;
  left: 20px;
  color: #cdcecd;
  font-size: 14px;
  z-index: 3;
  background: rgba(0, 0, 0, 0.7);
  padding: 10px;
}

.flow-formulas p {
  margin: 5px 0;
  text-shadow: 0 0 5px rgba(255, 255, 255, 0.3);
}
.matrix-title {
  font-size: 16px;
  color: #fff;
  margin-bottom: 12px;
  padding-left: 4px;
}
</style>